
package com.guang.mybatisplusgenerate.jdbc.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guang.mybatisplusgenerate.jdbc.dao.AccountMapper;
import com.guang.mybatisplusgenerate.jdbc.model.domain.Account;
import com.guang.mybatisplusgenerate.jdbc.service.AccountService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
* @Description 服务类实现
* @Author liguang
* @Date 2024-05-25
*/
@Service
@AllArgsConstructor
@Slf4j
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService {

// =======================================测试一：正常使用===========================================================
/*
    @Override
    @Transactional
    public void doHandlTransaction(){
//        LambdaQueryChainWrapper<Account> wrapper = new LambdaQueryChainWrapper<>(baseMapper);
//        wrapper.eq(Account::getId,37L);
//        Account account1 = wrapper.one();
//        wrapper.clear();
//        wrapper.eq(Account::getId,36L);
//        Account account2 = wrapper.one();
        // 分别来进行操作
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,37L).set(Account::getName,"limeng");
        boolean update = updateChainWrapper.update();
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);

        // 错误使用案例
        // updateAccount();
        // 正确使用案例
        AccountService currentProxy = (AccountService) AopContext.currentProxy();
        currentProxy.updateAccount();
    }


    // 正常使用
    @Transactional
    public void updateAccount(){
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,36L).set(Account::getName,"limeng");
        boolean update = updateChainWrapper.update();
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);
    }*/


    // =======================================测试二：事务方法A中调用事务B方法，事务B方法出现异常，A方法也需要进行回滚===========================================================
/*    @Override
    @Transactional
    public void doHandlTransaction(){
        // 分别来进行操作
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,37L).set(Account::getName,"meiheng");
        boolean update = updateChainWrapper.update();
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);

        // 错误使用案例
        // updateAccount();
        // 正确使用案例
        AccountService currentProxy = (AccountService) AopContext.currentProxy();
        try {
            currentProxy.updateAccount();
        } catch (Exception e) {
            log.error("调用updateAccount方法出现异常！虽然当前事务在这里catch住了，但是想要整个事务依然进行回滚需要设置下面的");
            // 但是只要补上下面这行代码，外层事务就会回滚！因为使用的是相同事务，事务具备了ACID的特性，要么提交成功，要么提交失败
            // 如果想要事务方法A成功，但是事务方法B失败，那么只需要让其让事务方法B和事务方法A不使用同一个事务即可， 事务方法A可以使用@Transactional，而事务方法B可以使用@Transactional(propagation = Propagation.REQUIRES_NEW)
            // 因为下面这个方法设置了rollbackOnly=true
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }


    // 正常使用
    @Transactional
    public void updateAccount(){
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,36L).set(Account::getName,"shenzhen");
        boolean update = updateChainWrapper.update();
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);
        int i = 1 / 0;
    }*/

    // =======================================测试三：事务方法A中出现异常，直接try..catch住，事务会进行提交以及如何让其回滚的方法===========================================================
/*    @Override
    @Transactional
    public void doHandlTransaction(){
        // 分别来进行操作
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,37L).set(Account::getName,"huizhou");
        boolean update = false;
        try {
            update = updateChainWrapper.update();
            int i=  1/0;
        } catch (Exception e) {
            log.error("直接将方法进行try..catch，但是整个方法会提交");
            // 要是不想让其进行提交，那么可以在这里设置
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);
    }


    // 正常使用
    @Transactional
    public void updateAccount(){
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,36L).set(Account::getName,"shenzhen");
        boolean update = updateChainWrapper.update();
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);
        int i = 1 / 0;
    }*/

 /*   // =======================================测试四：事务方法A中调用事务B方法，事务B方法出现异常，A方法需要进行提交===========================================================
    @Override
    @Transactional
    public void doHandlTransaction(){
        // 分别来进行操作
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,37L).set(Account::getName,"guangzhou");
        boolean update = updateChainWrapper.update();
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);

        // 错误使用案例
        // updateAccount();
        // 正确使用案例
        AccountService currentProxy = (AccountService) AopContext.currentProxy();
        try {
            currentProxy.updateAccount();
        } catch (Exception e) {
            log.error("调用updateAccount方法出现异常！虽然当前事务在这里catch住了，但是事务doHandlTransaction可以提交");
        }
    }


    // 正常使用
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateAccount(){
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,36L).set(Account::getName,"shenzhen");
        boolean update = updateChainWrapper.update();
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);
        int i = 1 / 0;
    }*/


    // =======================================测试五：事务执行前后执行哪些方法逻辑===========================================================
    @Override
    @Transactional
    public void doHandlTransaction(){
        // 分别来进行操作
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,37L).set(Account::getName,"guangzhou");
        boolean update = updateChainWrapper.update();
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);
        AccountService currentProxy = (AccountService) AopContext.currentProxy();
        try {
            currentProxy.updateAccount();
        } catch (Exception e) {
            log.error("调用updateAccount方法出现异常！虽然当前事务在这里catch住了，但是事务doHandlTransaction可以提交");
        }
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void beforeCompletion() {
               log.info("事务完成之前执行执行的操作");
            }

            @Override
            public void afterCompletion(int status) {
                log.info("事务完成之后执行执行的操作");
            }
        });

    }


    // 正常使用
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateAccount(){
        LambdaUpdateChainWrapper<Account> updateChainWrapper = new LambdaUpdateChainWrapper<>(baseMapper);
        updateChainWrapper.eq(Account::getId,36L).set(Account::getName,"shenzhen");
        boolean update = updateChainWrapper.update();
        log.info("当前事务name是：{}，更新成功：{}",TransactionSynchronizationManager.getCurrentTransactionName(),update);
        int i = 1 / 0;
    }
}
